package com.luis.toolbox.inbound;

import com.luis.toolbox.common.CommonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.concurrent.TimeUnit;

@Configuration
@EnableScheduling
public class ScheduleHandler implements ApplicationContextAware {
    private final Logger log = LoggerFactory.getLogger(ScheduleHandler.class);
    private final CommitState commitState;
    private ApplicationContext context;

    @Value("${buffer-size:1}")
    private int sizeToCommit;
    @Value("${delay-minute:1}")
    private int delayMinute;

    public ScheduleHandler(CommitState commitState) {
        this.commitState = commitState;
    }

    /*
      定义定时任务检查commit state的状态，
      如果发现触发了时间条件则主动进行一次提交
      触发条件1：累积条数超过定义的消息数量
      触发条件2：距离上次发送时间超过了定义的时间间隔
      */
    @Scheduled(fixedRateString = "${send-interval:500}")
    public void execute() {
        try{
            CommonHandler.DefaultGateway gateway = context.getBean("defaultGateway",
                    CommonHandler.DefaultGateway.class);
            synchronized (commitState){
                long gap = System.currentTimeMillis() - commitState.getLastCommitTime();
                if(commitState.getMessageStore().size() >= sizeToCommit
                    || (commitState.getMessageStore().size() > 0 && gap >= TimeUnit.MINUTES.toMillis(delayMinute))){
                    //满足了提交条件
                    String[] dataArray = commitState.getMessageStore().toArray(new String[0]);
                    if(dataArray.length > 0){
                        String req = String.join(System.lineSeparator(),dataArray);
                        commitState.commit().getMessageStore().clear();
                        gateway.sendToHandler(req);
                    }
                }
            }
        }catch(Exception ex){
            log.error("error when scheduler commit",ex);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
